home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / PROGRAMMING / DESKLIBC / SOURCES.ZIP / DeskLib / !DLSources / Libraries / Msgs / c / LoadFind < prev    next >
Text File  |  1995-07-09  |  8KB  |  328 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Msgs.LoadFind.c
  12.     Author:  Copyright © 1992 Jason Williams
  13.     Version: 1.00 (08 Apr 1992)
  14.     Purpose: MessageTrans-like message handling functions.
  15.              (If you want MessageTrans, use the SWI interface, if you want
  16.              high-level message handling, use this code...)
  17.  
  18.              NOTE: Although it may seem as if this chunk of code could be
  19.              split into smaller chunks, I don't see much point, as the
  20.              functions are all inter-dependent - there seems to be no point
  21.              in trying to use Msgs_Load without using the other functions
  22.              defined here (even using Msgs_printf calls Msgs_Lookup)
  23. */
  24.  
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30. #include "DeskLib:Core.h"
  31. #include "DeskLib:Error.h"
  32. #include "DeskLib:Resource.h"
  33. #include "DeskLib:TextFile.h"
  34. #include "DeskLib:Msgs.h"
  35.  
  36. #include "MsgsDefs.h"
  37.  
  38.  
  39.  
  40.  
  41. msgdefptr msgs_grouplist = NULL;
  42.  
  43.  
  44.  
  45.  
  46.  
  47. extern BOOL Msgs__MatchToken(char *tag1, char *tag2, BOOL wcallowed)
  48. {
  49.   int loop = 0;
  50.  
  51.   if (!wcallowed)   /* Don't allow wildcard matching when inserting records! */
  52.     return(MatchTokenI(tag1, tag2));
  53.  
  54.   while (loop < 9 && tag1[loop] != '\0' && tag2[loop] != '\0')
  55.   {
  56.     if (tag1[loop] == '*' || tag2[loop] == '*')
  57.       return(TRUE);
  58.  
  59.     if (tag1[loop] != tag2[loop])
  60.       return(FALSE);
  61.     loop++;
  62.   }
  63.  
  64.   if (tag1[loop] == '*' || tag2[loop] == '*')
  65.     return(TRUE);
  66.  
  67.   if (tag1[loop] != tag2[loop])
  68.     return(FALSE);
  69.  
  70.   return(TRUE);
  71. }
  72.  
  73.  
  74.  
  75. extern msgdefptr Msgs__Find(msgdefptr *liststart, char *tag,
  76.                             BOOL create, BOOL wcallowed)
  77. /* Find the given tag in either the group list or a message list (list header
  78.  * passed in as *liststart). If not found, possibly create a new record
  79.  * to hold this tag.
  80.  * Returns ptr to the found/created record, or NULL if not found/created
  81.  */
  82. {
  83.   msgdefptr ptr;
  84.  
  85.   ptr = *liststart;
  86.   while (ptr != NULL)
  87.   {
  88.     if (Msgs__MatchToken(tag, ptr->tag, wcallowed))
  89.       return(ptr);
  90.     ptr = ptr->next;
  91.   }
  92.  
  93.   if (!create)                     /* not found & don't want us to create it */
  94.     return(NULL);
  95.  
  96.   ptr = (msgdefptr) malloc(sizeof(msg_def));             /* create new group */
  97.   if (ptr != NULL)
  98.   {
  99.     ptr->next = *liststart;                   /* link in to head of msg list */
  100.     *liststart = ptr;
  101.  
  102.     strncpy(ptr->tag, tag, 9);
  103.     ptr->tag[9] = 0;
  104.     ptr->data.taglist = NULL;         /* equivalent to ptr->data.text = NULL */
  105.   }
  106.  
  107.   return(ptr);
  108. }
  109.  
  110.  
  111. static void CopyMessage(char *s1, char *s2, int maxlength);
  112.  
  113. extern BOOL Msgs_Lookup(char *tag, char *result, int maxlength)
  114. {
  115.   msgdefptr    ptr;
  116.   char         grouptag[10], msgtag[10];
  117.   register int index, index2;
  118.  
  119.   result[0] = '\0';
  120.   for(index = 0; index < 10; index++)
  121.   {
  122.     grouptag[index] = 0;
  123.     msgtag[index] = 0;
  124.   }
  125.  
  126.   index = 0;
  127.   while (index < 9)
  128.   {
  129.     if (tag[index] == '.')
  130.       break;
  131.  
  132.     grouptag[index] = tag[index];
  133.     index++;
  134.   }
  135.  
  136.   if (tag[index] != '.')   /* invalid tag  */
  137.     return(FALSE);
  138.  
  139.   index++;                 /* Skip the '.' */
  140.   index2 = 0;
  141.   while (index2 < 9)
  142.   {
  143.     if (tag[index] == ':' || tag[index] == '\0')
  144.       break;
  145.  
  146.     msgtag[index2++] = tag[index++];
  147.   }
  148.  
  149.   /* Find the group the message is in - use 2 passes, once with wildcards
  150.    * disabled, and then a second time with them enabled, so that order of
  151.    * definitiion is less important.
  152.    */
  153.   ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, FALSE);
  154.   if (ptr == NULL)  /* not found, so scan again */
  155.     ptr = Msgs__Find(&msgs_grouplist, grouptag, FALSE, TRUE);
  156.  
  157.  
  158.   /* Now, do the same  passes on the group's message list to find the actual
  159.    * message.
  160.    */
  161.   if (ptr != NULL)
  162.   {
  163.     msgdefptr ptr2;
  164.  
  165.     ptr2 = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, FALSE);
  166.     if (ptr2 == NULL)  /* not found, so scan again */
  167.       ptr = Msgs__Find(&(ptr->data.taglist), msgtag, FALSE, TRUE);
  168.     else
  169.       ptr = ptr2;
  170.   }
  171.  
  172.   if (ptr == NULL)  /* still not found - have we been supplied with default? */
  173.   {
  174.     if (tag[index] != '\0')
  175.     {
  176.       strncpy(result, &(tag[index + 1]), maxlength);
  177.       result[maxlength] = 0;
  178.       return(TRUE);                                /* return default       */
  179.     }
  180.     return(FALSE);                                 /* Failed completely    */
  181.   }
  182.  
  183.   CopyMessage(result, ptr->data.text, maxlength);  /* Return found message */
  184.   return(TRUE);
  185. }
  186.  
  187.  
  188.  
  189. static void CopyMessage(char *dest, char *src, int maxlength)
  190. {
  191.   register int  from = 0, to = 0, i;
  192.   register char c;
  193.   char includetag[24];
  194.  
  195.   while (from < maxlength - 1)
  196.   {
  197.     c = src[from];
  198.     if (c == 0)
  199.       break;
  200.  
  201.     if (c == '<')
  202.     {
  203.       if (src[from + 1] == '>')
  204.       {
  205.         from++;                     /* found "<>" - skip to output "<" only */
  206.         dest[to++] = '<';
  207.       }
  208.       else
  209.       {
  210.         from++;    /* Search from < to > to extract the include message tag */
  211.         i = 0;
  212.         while (c != '>')
  213.         {
  214.           c = src[from++];
  215.           includetag[i++] = c;
  216.         }
  217.         includetag[i - 1] = '\0';
  218.         from--;                         /* whoa boy! back up one character! */
  219.  
  220.         /*  Found include tag, so recurse on it to insert it into final
  221.          *  message at this point
  222.          */
  223.  
  224.         Msgs_Lookup(includetag, &(dest[to]), maxlength - to);
  225.  
  226.         /*  And now, we must search ahead from OUR "to" index (the start
  227.          *  of the section inserted) until we find the new end-of-string
  228.          */
  229.         while(dest[to] != '\0')
  230.           to++;
  231.       }
  232.     }
  233.     else
  234.       dest[to++] = c;
  235.  
  236.     from++;
  237.   }
  238.  
  239.   dest[to] = '\0';   /* Add string terminator */
  240. }
  241.  
  242.  
  243.  
  244. static BOOL AddMessage(char *grouptag, char *msgtag, char *message)
  245. {
  246.   char *msg;
  247.   msgdefptr ptr;
  248.  
  249.   msg = (char *) malloc(strlen(message) + 1);
  250.   if (msg == NULL)  return(Error_OutOfMemory(FALSE, "Messages"));
  251.   strcpy(msg, message);
  252.  
  253.   ptr = Msgs__Find(&msgs_grouplist, grouptag, TRUE, FALSE);
  254.   if (ptr != NULL)
  255.     ptr = Msgs__Find(&(ptr->data.taglist), msgtag, TRUE, FALSE);
  256.  
  257.   if (ptr != NULL)
  258.   {
  259.     if (ptr->data.text != NULL)
  260.       free(ptr->data.text);                  /* Overwrite previous occurence */
  261.  
  262.     ptr->data.text = msg;
  263.     return(TRUE);
  264.   }
  265.   return(FALSE);
  266. }
  267.  
  268.  
  269.  
  270. extern BOOL Msgs_LoadFile(char *leafname)
  271. /*  Merges the given messages file into the current list of messages
  272.  *  Messages with the same group.msg tag will be overwritten by the
  273.  *  new messages coming in from the file.
  274.  *
  275.  *  Expects lines of the form:
  276.  *    group.msg: message text continuing to newline
  277.  *  Leading spaces are ignored
  278.  */
  279. {
  280.   char filename[60];
  281.   char groupname[10], tagname[10];
  282.   char buffer[1024];
  283.   FILE *infile;
  284.   int  loop;
  285.   char ch;
  286.  
  287.   strcpy(filename, resource_pathname);
  288.   strcat(filename, leafname);
  289.  
  290.   infile = fopen(filename, "r");
  291.   if (infile == NULL)
  292.     return(FALSE);
  293.  
  294.   while (!feof(infile))
  295.   {
  296.     for (loop = 0; loop < 10; loop++)
  297.     {
  298.       groupname[loop] = 0;
  299.       tagname[loop] = 0;
  300.     }
  301.  
  302.     while (TRUE) /* Skip comments */
  303.     {
  304.       TextFile_SkipBlanks(infile);
  305.       if ((ch = getc(infile)) == '#')
  306.         TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
  307.       else
  308.       {
  309.         ungetc(ch, infile);
  310.         break;
  311.       }
  312.     }
  313.  
  314.     TextFile_ReadToDelimiter(infile, '.', groupname, 10);
  315.     TextFile_ReadToDelimiter(infile, ':', tagname, 10);
  316.     TextFile_ReadToDelimiter(infile, '\n', buffer, 510);
  317.  
  318.     if (!feof(infile) && !AddMessage(groupname, tagname, buffer))
  319.     {
  320.       fclose(infile);
  321.       return(FALSE);
  322.     }
  323.   }
  324.  
  325.   fclose(infile);
  326.   return(TRUE);
  327. }
  328.